#include <conio.h>
#include <graphics.h>
#include <stdio.h>
#include <math.h>
#include <windows.h>
#include <stdlib.h>

//引用引用Windows Multimedia API,可以调用音乐处理功能
#pragma comment(lib,"Winmm.lib")

#define high 800			//定义游戏画面尺寸
#define width 480

// 全局变量
IMAGE img_bk;				//定义背景图片
IMAGE img_gamestart_bk;		//定义游戏开始画面图片
IMAGE img_appearance_bk;	//定义游戏选择界面图片

//定义蓝球原版和蒙版图片
IMAGE img_blueball1;		
IMAGE img_blueball2;		
//定义篮球原版和蒙版图片
IMAGE img_basketball1;		
IMAGE img_basketball2;	
//定义网球原版和蒙版图片
IMAGE img_tennis1;		
IMAGE img_tennis2;		
//定义桌球原版和蒙版图片
IMAGE img_snooker1;		
IMAGE img_snooker2;		
//定义黑红篮球原版和蒙版图片
IMAGE img_blackbasketball1;			
IMAGE img_blackbasketball2;		
//定义黑绿篮球原版和蒙版图片
IMAGE img_greenbasketball1;			
IMAGE img_greenbasketball2;		
//定义球原版和蒙版图片
IMAGE img_purplebasketball1;			
IMAGE img_purplebasketball2;			
//定义球原版和蒙版图片
IMAGE img_purplesnooker1;		
IMAGE img_purplesnooker2;		

IMAGE img_ball_death;		//定义小球死亡图片
IMAGE img_zhu1;				//定义圆柱图片
IMAGE img_zhu2;				//定义圆柱蒙版图片
IMAGE img_logo;				//定义开始动画的图片

double ball_x,ball_y;		//小球位置
double ball_speed;			//小球速度
double ball_a;				//小球加速度

double bar_y1;               //以七个板为周期第一个板
double bar_y2;               //以七个板为周期第二个板
double bar_y3;               //以七个板为周期第三个板
double bar_y4;               //以七个板为周期第四个板
double bar_y5;               //以七个板为周期第五个板
double bar_y6;               //以七个板为周期第六个板
double bar_y7;               //以七个板为周期第七个板

int logo;					//开始播放开场动画

//选择小球颜色,0为蓝球,1为篮球,2为网球,3为台球,4为紫色台球,5为黑红篮球,6为黑绿篮球,7为紫色篮球
int ball_color;			
	
//游戏状态,0为初始菜单界面,1为正常游戏,2为游戏规则,3为暂停游戏界面,4为选择皮肤界面,5为死亡游戏界面
int gamestatus;	

//小球状态,0为反弹,1为死亡,2为下落
int ballstatus;

int score;					 //得分
int right;                   //转动幅度
double h;                    //背景上移高度
double change;               //每次画面上升高度
int begin;                   //使速度变化


//下面是各种使用到的函数
void logoStart();            //logo开始界面的淡出
void startmenu();            // 显示游戏开始菜单画面
void appearance_choose();    //选择小球皮肤颜色
void startup();              //数据初始化
void show();                 // 显示游戏画面
void rules();                //游戏开始后如果点击规则则显示游戏规则，游戏状态为2
void pause();                //暂停游戏游戏状态为3
void readRecordFile();       //读取游戏数据文件存档
void writeRecordFile();      //存储游戏数据文件存档
void move();                 //模拟小球自由落体
void ball_dowm();
void ball_back();            //小球反弹
void death();                //死亡，游戏状态为5
void gameover();             //游戏结束
void updateWithinput();      // 与用户输入有关的更新
void updateWithoutinput();   // 与用户输入无关的更新

void logoStart()			 //logo开始界面
{	
	BeginBatchDraw();

	putimage(0, 0, 480, 800, &img_logo,0,0);
	setbkmode(TRANSPARENT);								//背景透明

	settextcolor(WHITE);								//字体颜色
	settextstyle(20, 10, _T("宋体"));					//字体类型
	outtextxy(width/2-80, high - 40,_T("--按空格键继续--"));		//新的游戏

	char input;
	if (kbhit())
	{
		input = getch();

		if (input == ' ')
		{
			logo = 0;
		}		
	}

	FlushBatchDraw();
	
	EndBatchDraw();
}

void startmenu()			// 显示游戏开始菜单画面
{   
	// 显示背景
	putimage(0, 0, 480, 800, &img_gamestart_bk,0,0);

	//显示游戏界面的文字

	setbkmode(TRANSPARENT);								//背景显示透明

	//开始游戏
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 200,_T("NEW GAME"));			//新的游戏
	rectangle(width/2-150, 200, width/2+50, 250);		//矩形边框

	//规则
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 300,_T("RULES"));			//游戏规则
	rectangle(width/2-150, 300, width/2-10, 350);		//矩形边框

	//读取存档
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 400,_T("APPEARANCE"));		//读取存档
	rectangle(width/2-150, 400, width/2+110, 450);		//矩形边框

	//读取存档
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 500,_T("READ ARCHIVED"));	//读取存档
	rectangle(width/2-150, 500, width/2+180, 550);		//矩形边框

	//游戏信息
	settextcolor(BLUE);									//字体颜色
	settextstyle(20, 0, _T("宋体"));					//字体类型
	outtextxy(0, 10, _T("制作人：李帅，王泽一"));
	
	FlushBatchDraw();
	
	//下面判断鼠标的点击
	MOUSEMSG m;						// 定义鼠标消息

	while (MouseHit())
	{
	m = GetMouseMsg();				// 获取鼠标信息
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息,点击开始游戏
		if (m.x >= (width/2 - 150) && m.x <= (width/2 + 50))
		{
			if (m.y >= 200 && m.y <= 250)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				gamestatus = 1;
			}
					
			EndBatchDraw();
		}	
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息，点击显示规则
		if (m.x >= (width/2 - 150) && m.x <= (width/2 - 10))
		{
			if (m.y >= 300 && m.y <= 350)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL);
				
				gamestatus = 2;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息，点击选择皮肤
		if (m.x >= (width/2 - 150) && m.x <= (width/2 + 110))
		{
			if (m.y >= 400 && m.y <= 450)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL);
				
				gamestatus = 4;
			}
				
			EndBatchDraw();
		}	
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息，点击读取存档
		if (m.x >= (width/2 - 150) && m.x <= (width/2 + 180))
		{
			if (m.y >= 500 && m.y <= 550)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//读取存档
				readRecordFile();

				gamestatus = 1;
			}

			EndBatchDraw();
		}	
	}
}

void appearance_choose() //选择小球皮肤颜色
{
	putimage(0,0,480,800,&img_appearance_bk,0,0);	//显示背景
	//setbkmode(TRANSPARENT);							//背景透明

	//显示蓝球
	putimage(width/2-100, 100, &img_blueball2, NOTSRCERASE);
	putimage(width/2-100, 100, &img_blueball1, SRCINVERT);
	//显示篮球
	putimage(width/2-100, 250, &img_basketball2, NOTSRCERASE);
	putimage(width/2-100, 250, &img_basketball1, SRCINVERT);
	//显示网球
	putimage(width/2-100, 400, &img_tennis2, NOTSRCERASE);
	putimage(width/2-100, 400, &img_tennis1, SRCINVERT);
	//显示台球
	putimage(width/2-100, 550, &img_snooker2, NOTSRCERASE);
	putimage(width/2-100, 550, &img_snooker1, SRCINVERT);
	//显示紫色台球
	putimage(width/2+100, 100, &img_purplesnooker2, NOTSRCERASE);
	putimage(width/2+100, 100, &img_purplesnooker1, SRCINVERT);
	//显示黑红蓝球
	putimage(width/2+100, 250, &img_blackbasketball2, NOTSRCERASE);
	putimage(width/2+100, 250, &img_blackbasketball1, SRCINVERT);
	//显示黑绿蓝球
	putimage(width/2+100, 400, &img_greenbasketball2, NOTSRCERASE);
	putimage(width/2+100, 400, &img_greenbasketball1, SRCINVERT);
	//显示紫色蓝球
	putimage(width/2+100, 550, &img_purplebasketball2, NOTSRCERASE);
	putimage(width/2+100, 550, &img_purplebasketball1, SRCINVERT);
	
	FlushBatchDraw();

	MOUSEMSG m;						// 定义鼠标消息
	while(MouseHit())
	{
	m = GetMouseMsg();				// 获取鼠标信息
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 100) && m.x <= (width/2 - 74))
		{
			if (m.y >= 100 && m.y <= 126)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示蓝球
				ball_color = 0;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 100) && m.x <= (width/2 - 74))
		{
			if (m.y >= 250 && m.y <= 276)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示篮球
				ball_color = 1;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 100) && m.x <= (width/2 - 74))
		{
			if (m.y >= 400 && m.y <= 426)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示网球
				ball_color = 2;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 100) && m.x <= (width/2 - 74))
		{
			if (m.y >= 550 && m.y <= 576)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示台球
				ball_color = 3;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 + 100) && m.x <= (width/2 + 126))
		{
			if (m.y >= 100 && m.y <= 126)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示紫色台球
				ball_color = 4;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 + 100) && m.x <= (width/2 + 126))
		{
			if (m.y >= 250 && m.y <= 276)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示黑红篮球
				ball_color = 5;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 + 100) && m.x <= (width/2 + 126))
		{
			if (m.y >= 400 && m.y <= 426)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示黑绿篮球
				ball_color = 6;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 + 100) && m.x <= (width/2 + 126))
		{
			if (m.y >= 550 && m.y <= 576)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//显示紫色篮球
				ball_color = 7;

				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	
	}
}

void rules()						//游戏开始后如果点击规则则显示游戏规则，游戏状态为2
{
	putimage(0, 0, 480, 800, &img_gamestart_bk,0,0);//显示背景
	setbkmode(TRANSPARENT);							//背景透明

	//显示游戏界面的文字

	//玩法说明
	settextcolor(RED);								//字体颜色
	settextstyle(40, 0, _T("宋体"));				//字体类型
	outtextxy(20, 250, _T("玩法说明："));
	rectangle(20, 250, width/2-30, 290);			//矩形边框

	//游戏玩法介绍
	settextcolor(RED);								//字体颜色
	settextstyle(40, 0, _T("宋体"));				//字体类型
	outtextxy(20, 300, _T("利用键盘a,d移动轮盘"));
	rectangle(20, 300, width/2+180, 340);			//矩形边框

	settextcolor(RED);								//字体颜色
	settextstyle(40, 0, _T("宋体"));				//字体类型
	outtextxy(20, 350, _T("小球碰到黄色的轮盘死亡"));
	rectangle(20, 350, width/2+220, 390);			//矩形边框

	//暂停游戏
	outtextxy(20, 400, _T("按空格暂停游戏"));
	rectangle(20, 400, width/2+60, 440);			//矩形边框

	//开始游戏
	settextstyle(50, 0, _T("宋体"));
	settextcolor(BLUE);
	outtextxy(width/2, 500, _T("START"));
	rectangle(width/2, 500, width/2+120, 550);		//矩形边框

	FlushBatchDraw();

	MOUSEMSG m;						// 定义鼠标消息
	while(MouseHit())
	{
	m = GetMouseMsg();				// 获取鼠标信息
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= width/2 && m.x <= width/2 + 120)
		{
			if (m.y >= 500 && m.y <= 550)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				//开始游戏
				gamestatus = 1;
			}
				
			EndBatchDraw();
		}	
	}
}

void pause()					//暂停游戏游戏状态为3
{
	// 显示背景
	putimage(0, 0, 480, 800, &img_gamestart_bk,0,0);
	setbkmode(TRANSPARENT);								//背景显示透明

	//显示游戏界面的文字

	//继续游戏
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-100, 300,_T("继续"));				//新的游戏
	rectangle(width/2-100, 300, width/2+10, 350);		//矩形边框

	//存档
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-100, 400,_T("存档"));				//游戏规则
	rectangle(width/2-100, 400, width/2+10, 450);		//矩形边框

	//退出游戏
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-100, 500, _T("退出游戏"));
	rectangle(width/2-100, 500, width/2+90, 550);		//矩形边框

	FlushBatchDraw();

	
	//下面判断鼠标信息
	MOUSEMSG m;						// 定义鼠标消息
	while (MouseHit())
	{
	m = GetMouseMsg();				// 获取鼠标信息
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 100) && m.x <= (width/2 + 10))
		{
			if (m.y >= 300 && m.y <= 400)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 	
				
				gamestatus = 1;
			}
				
			if (m.y >= 400 && m.y <= 450)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				writeRecordFile();
			}
				
			EndBatchDraw();
		}

	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 100) && m.x <= (width/2 + 90))
		{
			if (m.y >= 500 && m.y <= 550)
			{
				// 先把前面一次的音乐关闭
				mciSendString("close fgmusic", NULL, 0, NULL); 
				// 打开弹跳音乐
				mciSendString("open .\\点击音效.mp3 alias fgmusic", NULL, 0, NULL); 
				// 仅播放一次
				mciSendString("play fgmusic", NULL, 0, NULL); 

				exit(0);
			}

			EndBatchDraw();
		}	
	}
}

void readRecordFile()				//读取游戏数据文件存档
{ 
	FILE *fp;
	fp = fopen(".\\gameRecord.dat","r");

	fscanf(fp,"%f %f %f %d",&ball_x,&ball_y,&ball_speed,&score);
	fclose(fp);
}

void writeRecordFile()				//存储游戏数据文件存档
{
	FILE *fp;
	fp = fopen(".\\gameRecord.dat","w");

	fprintf(fp,"%f %f %f %d",&ball_x,&ball_y,&ball_speed,&score);
	fclose(fp);
}

void death()						//死亡，游戏状态为5
{
	// 显示背景
	putimage(0, 0, 480, 800, &img_gamestart_bk,0,0);
	setbkmode(TRANSPARENT);								//背景显示透明

	//显示游戏界面的文字
	//GAME OVER
    settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 200,_T("CAME OVER"));		//新的游戏
	rectangle(width/2-150, 200, width/2+75, 250);		//矩形边框

	//重新开始游戏
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 300,_T("AGAIN"));			//新的游戏
	rectangle(width/2-150, 300, width/2-10, 350);		//矩形边框

	//存档
	settextcolor(RED);									//字体颜色
	settextstyle(50, 0, _T("宋体"));					//字体类型
	outtextxy(width/2-150, 400,_T("EXIT"));				//游戏规则
	rectangle(width/2-150, 400, width/2-50, 450);		//矩形边框

	FlushBatchDraw();
	
	//下面判断鼠标信息
	MOUSEMSG m;						// 定义鼠标消息
	while (MouseHit())
	{
	m = GetMouseMsg();				// 获取鼠标信息
	
	if (m.uMsg == WM_LBUTTONDOWN)	//左键按下消息
		if (m.x >= (width/2 - 150) && m.x <= (width/2 - 10))
		{
			if (m.y >= 300 && m.y <= 350)
			{
				//更新游戏数据
				ball_y = 30;
   	            bar_y1 = 200;
	            bar_y2 = 500;
	            bar_y3 = 800;
            	bar_y4 = 1100;
            	bar_y5 = 1400;
            	bar_y6 = 1700;
            	bar_y7 = 2000;

            	change = 300;

            	ball_speed = 1.2;			//初始化小球速度
            	ball_a = 9.8 / 30;			//初始化小球重力加速度	

	            score = 0;					//得分归零
	            right = 3;
	            h = 0;
	            begin = 1;
				gamestatus = 0;				//显示游戏菜单
			}
			else if (m.y >= 400 && m.y <= 450)
				exit(0);					//退出游戏

			EndBatchDraw();
		}	
	}
}

void startup()					//数据初始化
{
	initgraph(width, high);

	//下面获取各种图片
	//开始动画
	loadimage(&img_logo,".\\logo.jpg");

	//游戏背景
	loadimage(&img_bk,".\\背景图1.jpg");
	//开始界面背景
	loadimage(&img_gamestart_bk,".\\开始界面.jpg");

	//选择皮肤界面背景
	loadimage(&img_appearance_bk,".\\选择界面背景.JFIF");

	//输入各种小球

	//蓝球
	loadimage(&img_blueball1,".\\蓝球.jpg");
	loadimage(&img_blueball2,".\\蓝球蒙版.jpg");
	//篮球
	loadimage(&img_basketball1,".\\篮球.jpg");
	loadimage(&img_basketball2,".\\篮球蒙版.jpg");
	//网球
	loadimage(&img_tennis1,".\\网球.jpg");
	loadimage(&img_tennis2,".\\网球蒙版.jpg");
	//桌球
	loadimage(&img_snooker1,".\\桌球.jpg");
	loadimage(&img_snooker2,".\\桌球蒙版.jpg");
	//紫色台球
	loadimage(&img_purplesnooker1,".\\紫色台球.jpg");
	loadimage(&img_purplesnooker2,".\\紫色台球蒙版.jpg");
	//黑红篮球
	loadimage(&img_blackbasketball1,".\\黑红篮球.jpg");
	loadimage(&img_blackbasketball2,".\\黑红篮球蒙版.jpg");
	//黑绿篮球
	loadimage(&img_greenbasketball1,".\\黑绿篮球.jpg");
	loadimage(&img_greenbasketball2,".\\黑绿篮球蒙版.jpg");
	//紫色篮球
	loadimage(&img_purplebasketball1,".\\紫色篮球.jpg");
	loadimage(&img_purplebasketball2,".\\紫色篮球蒙版.jpg");

	//下面初始化各种数据
	ball_x = width/2 - 5;		//初始化小球位置
	ball_y = 30;
	
   	bar_y1 = 200;
	bar_y2 = 500;
	bar_y3 = 800;
	bar_y4 = 1100;
	bar_y5 = 1400;
	bar_y6 = 1700;
	bar_y7 = 2000;


	ball_speed = 1.2;			//初始化小球速度
	ball_a = 9.8 / 30;			//初始化小球重力加速度	

	logo = 1;
	gamestatus = 0;

	score = 0;

	change = 300;
	right = 3;
	h = 0;
	begin = 1;

	BeginBatchDraw();

	//打开背景音乐
	mciSendString("open .\\背景音乐.mp3 alias bkmusic", NULL, 0, NULL);
	//循环播放
	mciSendString("play bkmusic repeat", NULL, 0, NULL); 
}

void show()					// 显示游戏画面
{
	while (logo)			//开始游戏动画
	{
		logoStart();
	}

	while (gamestatus == 0) //游戏状态为0,显示菜单界面
	{
		startmenu();
	}

	while (gamestatus == 2) //游戏状态为2,显示规则界面
	{
		rules();
	}
	
	while (gamestatus == 3)	//游戏状态为3,显示暂停界面
	{
		pause();
	}

	while (gamestatus == 4) //游戏状态为4,显示选择皮肤界面
	{
		appearance_choose();
	}

	while (gamestatus == 5) //游戏状态为5,显示死亡后界面
	{
		death();
	}
	
    //背景
	putimage(0,0,480,800,&img_bk,right*482.5,h*change);

	Sleep(5);

	//小球颜色选择
	switch (ball_color)
	{
		//选择蓝球
		case 0:		

			putimage(ball_x, ball_y, &img_blueball2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_blueball1, SRCINVERT);

			break;

		//选择篮球
		case 1:

			putimage(ball_x, ball_y, &img_basketball2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_basketball1, SRCINVERT);

			break;

		//选择网球
		case 2:

			putimage(ball_x, ball_y, &img_tennis2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_tennis1, SRCINVERT);

			break;

		//选择台球
		case 3:

			putimage(ball_x, ball_y, &img_snooker2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_snooker1, SRCINVERT);

			break;

		//选择紫色台球
		case 4:

			putimage(ball_x, ball_y, &img_purplesnooker2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_purplesnooker1, SRCINVERT);

			break;

		//选择黑红篮球
		case 5:

			putimage(ball_x, ball_y, &img_blackbasketball2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_blackbasketball1, SRCINVERT);

			break;

		//选择黑绿篮球
		case 6:

			putimage(ball_x, ball_y, &img_greenbasketball2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_greenbasketball1, SRCINVERT);

			break;

		//选择紫色篮球
		case 7:

			putimage(ball_x, ball_y, &img_purplebasketball2, NOTSRCERASE);
			putimage(ball_x, ball_y, &img_purplebasketball1, SRCINVERT);

			break;

	}

	//下面输出得分
	settextcolor(RED);								//字体颜色
	settextstyle(20, 0, _T("宋体"));				//字体类型
	outtextxy(40, high-50, "得分：");

	char s[5];
	sprintf(s,"%d", score);
	settextcolor(RED);								//字体颜色
	settextstyle(40, 0, _T("宋体"));				//字体类型
	outtextxy(90, high-50, s);
	FlushBatchDraw();

	Sleep(20);				// 延时	
}	

void updateWithInput()			// 与用户输入有关的更新
{	
	char input;
	
	if(kbhit())
	{
		input = getch();

		if(input == 27)			//判断是否退出游戏
		{
			// 先把前面一次的音乐关闭
			mciSendString("close fgmusic", NULL, 0, NULL); 
			// 打开弹跳音乐
			mciSendString("open .\\暂停.mp3 alias fgmusic", NULL, 0, NULL); 
			// 仅播放一次
			mciSendString("play fgmusic", NULL, 0, NULL); 

			gamestatus = 3;
		}

		if (input == 'a')  //判断转盘向左转动
		{
			right--;

			Sleep(15);

			if (right < 0)
				right = 11;
		}
		if (input == 'd')  // 判断转盘向右转动
		{
			right++;

			Sleep(15);

			if (right > 11)
				 right = 0;
		}  
	}
}

void ball_down()					//控制小球在板块中间下落
{
	h += 0.7489;
	change += 0.7542;

	Sleep(10);

	ball_speed *= 0.86;
	ball_y -= ball_speed;
}

void move()					//模拟小球自由落体
{
	//小球下落
	if (ball_y <= high)
	{
		ball_y += ball_speed;
		ball_speed += ball_a;
	}

    if (ball_y >= (bar_y1+5) && ball_y <= (bar_y1+20))  //判断第一行
	{
		if ((right == 11) || (right == 2) || (right == 3) || (right == 4) || (right == 5) || (right == 6) || (right == 7) || (right == 8) || (right == 0))
		{
			ball_back();
		}
		else if (right == 1)
		{
	        gamestatus = 5;
		}

	    else
		{
			ball_down();

			bar_y1 = bar_y1 - h*change;
			bar_y2 = bar_y2 - h*change;
			begin  = 1;
			score++;
		}	
	}
		 
	if ((ball_y >= bar_y2 + 5) && (ball_y <= bar_y2 + 20))    //判断第二行
	{
		if ((right == 5) || (right == 6) || (right == 9) || (right == 7) || (right == 8))
		{
			ball_back();
		}	
		else if ((right == 1)||(right == 0))
		{
			gamestatus = 5;
		}
        
		else
		{
			ball_down();

			bar_y1 = bar_y1-h*change;
			bar_y2 = bar_y2-h*change;
			bar_y3 = bar_y3-h*change;
			begin  = 1;
			score++;
		}
	}

	if (ball_y >= (bar_y3+5) && ball_y <= (bar_y3+20))    //判断第三行
	{
		if ((right == 3) || (right == 4) || (right == 5) || (right == 6))
		{
			ball_back();
		}
		else if ((right == 10) || (right == 11))
		{
			gamestatus = 5;
		}
        
		else
		{
			ball_down();

			bar_y1 = bar_y1-h*change;
			bar_y2 = bar_y2-h*change;
		    bar_y3 = bar_y3-h*change;
			bar_y4 = bar_y4-h*change;
			begin  = 1;
			score++;	
		}
	}

	if (ball_y >= (bar_y4+5) && ball_y <= (bar_y4+20))    //判断第四行
	{
		if ((right == 3) || (right == 4) || (right == 6) || (right == 0) || (right == 2) || (right == 1))
		{	  
			ball_back();
		}
		else if (right == 5)
		{
			gamestatus = 5;
		}
        
		else
		{
			ball_down();

			bar_y2 = bar_y2-h*change;
            bar_y3 = bar_y3-h*change;
			bar_y4 = bar_y4-h*change;
			bar_y5 = bar_y5-h*change;
			begin  = 1;
			score++;
		}
	}

	if (ball_y >= (bar_y5+5) && ball_y <= (bar_y5+20))    //判断第五行
	{
		if((right == 3) || (right == 4) || (right == 5) || (right == 2) || (right == 11))
		{
			ball_back();
		}
		else if ((right == 10) || (right == 9))
		{
			gamestatus = 5;
		}
        
		else
		{
			ball_down();

			bar_y4 = bar_y4-h*change;
			bar_y5 = bar_y5-h*change;
			bar_y6 = bar_y6-h*change;
			begin  = 1;
			score++;		
		}
	}

	if (ball_y >= (bar_y6+5) && ball_y <= (bar_y6+20))    //判断第六行
	{
		if ((right == 3) || (right == 7) || (right == 8))
		{
			ball_down();

			bar_y5 = bar_y5-h*change;
			bar_y6 = bar_y6-h*change;
			bar_y7 = bar_y7-h*change;
			begin  = 1;
			score++;
		}
	    else if ((right == 9) || (right == 10) || (right == 11))
		{
			gamestatus = 5;
		}
        
		else
		{
			ball_back();
		}
	}

	if (ball_y >= (bar_y7+5) && ball_y <= (bar_y7+20))    //判断第七行
	{
		if ((right == 0) || (right == 1) || (right == 11) || (right == 10))
		{
			right = rand() % 11;							//重新循环游戏

			if ((right == 9) || (right == 10) || (right == 1))
				right += 2;

			ball_down();

			bar_y1 = 200;
	        bar_y2 = 500;
            bar_y3 = 800;
            bar_y4 = 1100;
            bar_y5 = 1400;
            bar_y6 = 1700;
            bar_y7 = 2000;
			begin  = 1;
			score++;
		}
		else if ((right == 4) || (right == 5))
		{
			gamestatus = 5;
		}
        
		else
		{
			ball_back();
		}
	
	}
}

void ball_back()			//小球反弹
{	
	if (begin == 1)
	{
		ball_speed = -ball_speed * 0.93;
		begin = 0;
	}
	else
		ball_speed = -ball_speed;

	// 先把前面一次的音乐关闭
	mciSendString("close fgmusic", NULL, 0, NULL); 
	// 打开弹跳音乐
	mciSendString("open .\\小球弹跳声音.mp4 alias fgmusic", NULL, 0, NULL); 
	// 仅播放一次
	mciSendString("play fgmusic", NULL, 0, NULL); 
}

void updateWithoutInput()	// 与用户输入无关的更新
{
	move();
 
	if (gamestatus == 5)//判断是否死亡
	{
		// 先把前面一次的音乐关闭
		mciSendString("close fgmusic", NULL, 0, NULL); 
		// 打开弹跳音乐
		mciSendString("open .\\death.mp3 alias fgmusic", NULL, 0, NULL); 
		// 仅播放一次
		mciSendString("play fgmusic", NULL, 0, NULL); 

		death();			//死亡界面
	}
}

void gameover()  //游戏结束
{
	EndBatchDraw();
	closegraph();
}

int main()
{
	startup();						// 数据初始化
    
	while(1)
	{
		updateWithoutInput();		// 与用户输入无关的更新
		updateWithInput();			// 与用户输入有关的更新
		show();						// 显示游戏画面
	}

	gameover();						// 游戏结束、后续处理

	return 0;
}